package com.mini.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.mini.client.MiniAdminClient;
import com.mini.client.MiniDataAttnClient;
import com.mini.conditon.BfDataCondition;
import com.mini.config.BusinessException;
import com.mini.constant.XcxOrderState;
import com.mini.model.*;
import com.mini.repository.BusinessBigLessonOrderRepository;
import com.mini.repository.BusinessBigOrderChanceRepository;
import com.mini.repository.BusinessTeacherInfoRepository;
import com.mini.util.CalendarUtil;
import com.mini.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class BusinessBigLessonOrderService extends BaseService{

    @Autowired
    private BusinessBigLessonOrderRepository bigLessonOrderRepository;

    @Autowired
    private BusinessBigOrderChanceRepository bigOrderChanceRepository;

    @Autowired
    private BusinessTeacherInfoRepository businessTeacherInfoRepository;

    @Autowired
    private BusinessTraditionChanceService traditionChanceService;

    @Autowired
    private MiniDataAttnClient miniDataAttnClient;

    @Autowired
    private MiniAdminService miniAdminService;

    protected final static String company_system = "飞天系统";
    protected final static String rowkey_suffix = "ft";


    public List<BusinessBigLessonOrderVO> bigOrderSimpleList(Collection<Long> chanceIds){
        List<BusinessBigLessonOrderVO> orderVOs = new ArrayList<>();
        if(CollectionUtils.isEmpty(chanceIds)){
            return orderVOs;
        }
        List<BusinessBigOrderChance> relateds = bigOrderChanceRepository.findByChanceIdIn(chanceIds);
        if(CollectionUtils.isEmpty(relateds)){
            return orderVOs;
        }

        Map<Long, List<BusinessBigOrderChance>> chanceOrderNoMap = relateds.stream().collect(Collectors.groupingBy(BusinessBigOrderChance::getChanceId));
        Set<String> orderNos = relateds.stream().map(BusinessBigOrderChance::getOrderNo).collect(Collectors.toSet());

        List<BusinessBigLessonOrder> orders = bigLessonOrderRepository.findByOrderNoIn(orderNos);

        if(CollectionUtils.isEmpty(orders)){
            return orderVOs;
        }
        Map<String, BusinessBigLessonOrder> orderMap = orders.stream().collect(Collectors.toMap(BusinessBigLessonOrder::getOrderNo, o->o, (o1,o2)->o1));


        for(Map.Entry<Long, List<BusinessBigOrderChance>> entry : chanceOrderNoMap.entrySet()){
            Long chanceId = entry.getKey();
            List<BusinessBigOrderChance> orderRelateds = entry.getValue();

            List<BusinessBigLessonOrder> chanceOrders = new ArrayList<>();
            for(BusinessBigOrderChance related : orderRelateds){
                String orderNo = related.getOrderNo();
                BusinessBigLessonOrder order = orderMap.get(orderNo);
                if(order != null){
                    chanceOrders.add(order);
                }
            }

            if(CollectionUtils.isEmpty(chanceOrders)) {
               continue;
            }

            //排序-倒叙
            chanceOrders.sort((o1, o2) -> {
                Date finishTime1 = o1.getPayFinishTime();
                Date finishTime2 = o2.getPayFinishTime();
                Date createTime1 = o1.getOrderCreateTime();
                Date createTime2 = o2.getOrderCreateTime();
                if (finishTime1 == null || finishTime2 == null) {
                    return createTime2.compareTo(createTime1);
                } else {
                    return finishTime2.compareTo(finishTime1);
                }
            });

            BusinessBigLessonOrder order = chanceOrders.get(0);
            BusinessBigLessonOrderVO vo = new BusinessBigLessonOrderVO();
            BeanUtil.copyProperties(order, vo);
            vo.setChanceId(chanceId);
            orderVOs.add(vo);

        }

        if(CollectionUtils.isEmpty(orderVOs)){
            return orderVOs;
        }

        List<String> filterOrderNos = orderVOs.stream().map(BusinessBigLessonOrder::getOrderNo).collect(Collectors.toList());
        Map<String, ClassInfoWithOrder> orderClassMap = getBigClassByOrder(filterOrderNos);

        for(BusinessBigLessonOrderVO vo : orderVOs){

            //班次信息
            if(orderClassMap != null ){
                ClassInfoWithOrder classInfoWithOrder = orderClassMap.get(vo.getOrderNo());

                if(classInfoWithOrder != null){
                    vo.setClassName(classInfoWithOrder.getClassName());
                }
            }

        }

        return orderVOs;
    }

    public List<BusinessBigLessonOrderVO> bigOrderList(Long chanceId){
        if(chanceId == null){
            return null;
        }

        List<BusinessBigOrderChance> relateds = bigOrderChanceRepository.findByChanceId(chanceId);
        if(CollectionUtils.isEmpty(relateds)){
            return null;
        }

        BusinessTraditionChance chance = this.traditionChanceService.findOne(chanceId);

        List<String> orderNos = relateds.stream().map(BusinessBigOrderChance::getOrderNo).collect(Collectors.toList());

        List<BusinessBigLessonOrder> orders = bigLessonOrderRepository.findByOrderNoIn(orderNos);

        if(CollectionUtils.isEmpty(orders)){
            return null;
        }

        //班次信息
        Map<String, ClassInfoWithOrder> orderClassMap = getBigClassByOrder(orderNos);

        //机会

        List<BusinessBigLessonOrderVO> orderVOS = new ArrayList();
        for(BusinessBigLessonOrder order : orders){
            BusinessBigLessonOrderVO vo = new BusinessBigLessonOrderVO();
            BeanUtil.copyProperties(order, vo);

            //机会
            vo.setChance(chance);
            vo.setChanceId(chanceId);

            //班次信息
            if(orderClassMap != null ){
                ClassInfoWithOrder classInfoWithOrder = orderClassMap.get(order.getOrderNo());

                if(classInfoWithOrder != null){
                    vo.setClassName(classInfoWithOrder.getClassName());
                }

            }

            orderVOS.add(vo);
        }


        return orderVOS;
    }

    public List<BusinessBigOrderLogVO> bigOrderLogByOrderNo(String orderNo){
        List<BusinessBigOrderLogVO> list = new ArrayList();
        if(StringUtils.isBlank(orderNo)){
            return list;
        }

        BusinessBigLessonOrder order = this.bigLessonOrderRepository.findOne(orderNo);

        //生成日志
        BusinessBigLessonOrder.OrderState orderState = BusinessBigLessonOrder.OrderState.getByState(order.getOrderState());
        if(orderState == null){
            return list;
        }

        String operationFormat = "康德同步飞天：报名单号%s，状态 %s";
        switch(orderState){

            case PAYING: {
                list.add(new BusinessBigOrderLogVO(order.getOrderNo(), order.getOrderCreateTime(), String.format(operationFormat, order.getOrderNo(), order.getOrderStateStr()), order.getOrderState()) );
                break;
            }
            case PAY_FINISH: {
                list.add(new BusinessBigOrderLogVO(order.getOrderNo(), order.getPayFinishTime(), String.format(operationFormat, order.getOrderNo(), order.getOrderStateStr()), order.getOrderState()) );
                break;
            }
            case PAY_CANCEL: {
                list.add(new BusinessBigOrderLogVO(order.getOrderNo(), order.getOrderCreateTime(), String.format(operationFormat, order.getOrderNo(), order.getOrderStateStr()), order.getOrderState()));
                break;
            }
            case PAY_REFUND_SUCCESS: {
                list.add(new BusinessBigOrderLogVO(order.getOrderNo(), order.getOrderCreateTime(), String.format(operationFormat, order.getOrderNo(), order.getOrderStateStr()), order.getOrderState()));
                break;
            }
            default:{}
        }


        return list;
    }


    public boolean syncBigOrder(BusinessBigLessonOrder order){

        //同步到数据

        //验证数据

        //现查询订单表有没有
        String orderNo = order.getOrderNo();
        String phoneNo = order.getPhoneNumber();

        BusinessBigLessonOrder orderRecord = this.bigLessonOrderRepository.findOne(orderNo);
        //如果订单表有，再查询订单机会表有没有关联记录
        if(orderRecord != null){
            //更新大课表
            saveOrder(order);

            BusinessBigOrderChance relateChance = this.bigOrderChanceRepository.findOne(orderNo);
            if(relateChance == null){
                // 找机会
                BusinessChancePhone chancePhone = traditionChanceService.findPhone(encryptField(phoneNo));

                if(chancePhone != null){
                    this.saveOrderChance(order, chancePhone);
                }
            }

            return true;
        }else {

            //查找机会


            BusinessChancePhone chancePhone = traditionChanceService.findPhone(encryptField(phoneNo));

            if(chancePhone != null){

                saveOrder(order);

                this.saveOrderChance(order, chancePhone);
                //保存订单机会关系

                return true;
            }
        }


        return false;
    }



    private BusinessBigLessonOrder saveOrder(BusinessBigLessonOrder record){

        BusinessBigLessonOrder existRecord = this.bigLessonOrderRepository.findOne(record.getOrderNo());
        if(existRecord != null){
            record.setCreateTime(existRecord.getCreateTime());
        }
        record = (BusinessBigLessonOrder) this.encryptObj(record);
        record.setUpdateTime(new Date());
        return bigLessonOrderRepository.save(record);
    }

    private BusinessBigOrderChance saveOrderChance(BusinessBigLessonOrder order, BusinessChancePhone chancePhone){
        String orderNo = order.getOrderNo();
        String orderState = order.getOrderState();
        Float payAmount = order.getPayAmount();

        if(bigOrderChanceRepository.exists(orderNo)){
            log.info("订单机会记录已存在: orderNo={}, chanceId={}" + orderNo, chancePhone);
            return bigOrderChanceRepository.findOne(orderNo);
        }

        //
        BusinessBigOrderChance record = new BusinessBigOrderChance(orderNo, chancePhone.getChanceId(), chancePhone.getTeacherId(), chancePhone.getId(), new Date());

        record = this.bigOrderChanceRepository.save(record);

        log.info("订单同步机会报名状态-是否同步：{},orderNo={},chanceId={}", (orderState.equals("15") && payAmount!=null &&payAmount>0f), orderNo, record.getChanceId());
        // 调用小鹏接口，通知大课已报名
        if(orderState.equals("15") && payAmount!=null &&payAmount>0f){
            log.info("订单同步机会报名状态-同步开始：orderNo={},chanceId={}", orderNo, record.getChanceId());
            traditionChanceService.updateChanceStatus(record.getChanceId(), ChanceBaseInfoVO.ChanceStatus.entered.code);
            log.info("订单同步机会报名状态-同步结束：orderNo={},chanceId={}", orderNo, record.getChanceId());
        }else if(orderState.equals("40") ){
            //TODO 退款学员怎么处理

        }

        return  record;
    }



    public Map<String, ClassInfoWithOrder> getBigClassByOrder(List<String> orderNos){
        Map<String, ClassInfoWithOrder> orderClassMap = new HashMap();
        if(CollectionUtils.isEmpty(orderNos)){
            return orderClassMap;
        }

        try{
            // 查询mini-data-attn服务，获取大课记录
            Map<String, List<String>> param = new HashMap();
            param.put("orderNos", orderNos);
            BusinessResult<List<ClassInfoWithOrder>> result = miniDataAttnClient.getBigClassByOrder(reqSign,param);
            if(result == null || result.getCode() != CommonResultMessage.SUCCESS.getCode().longValue()){
                return orderClassMap;
            }
            // 处理大课记录，按照订单号分组
            List<ClassInfoWithOrder> classInfos = result.getData();
            if(classInfos == null){
                return orderClassMap;
            }

            orderClassMap = classInfos.stream().collect(Collectors.toMap(ClassInfoWithOrder::getOrderNo, o->o, (o1,o2)->o2));

        }catch (Exception e){
            log.error("查询大课信息异常！", e);
        }

        return orderClassMap;
    }


    public List<BusinessBigOrderCountVO> countBigOrderByTeacherIds(BusinessBigOrderCountParam param){

        List<Object[]> list = bigLessonOrderRepository.countBigOrderByDay(param.getStart(), param.getEnd(), param.getTeacherIds());

        return listFromObject(list);

    }

    public List<BusinessBigOrderCountVO> countBigOrderByDay(String start, String end){

        List<Object[]> list = bigLessonOrderRepository.countBigOrderByDay(start, end);

        return listFromObject(list);

    }

    private List<BusinessBigOrderCountVO> listFromObject(List<Object[]> list){
        List<BusinessBigOrderCountVO> results = new ArrayList<>();

        if(CollectionUtils.isEmpty(list)){
            return results;
        }

        for(Object[] objects : list){
            if(objects == null || objects[0]==null){
                continue;
            }
            BigInteger teacherId = objects[0]==null ? null : (BigInteger) objects[0];
            BigInteger bigOrderCount = objects[1] == null ? null : (BigInteger) objects[1];
            Double bigOrderFee = objects[2]==null ? null : (Double) objects[2];

            BusinessBigOrderCountVO count = new BusinessBigOrderCountVO(teacherId==null ? null : teacherId.longValue() , bigOrderCount==null ? null : bigOrderCount.longValue(), bigOrderFee);

            results.add(count);
        }

        return results;
    }


    public PageResultVO<BfPackage>  pageByUpdateTime(BfDataCondition bfDataCondition){


        List<BfPackage> bfPackages = new ArrayList<>();
        //TODO
        int page = bfDataCondition.getPageNumber();
        page--;
        int pageSize = bfDataCondition.getPageSize();
        Sort sort = new Sort(Sort.Direction.fromString(bfDataCondition.getSortType()), Lists.newArrayList(bfDataCondition.getSortColumn()));
        PageRequest pageable = new PageRequest(page, pageSize, sort);
        Page<BusinessBigLessonOrder> orderPage = bigLessonOrderRepository.findAllByUpdateTimeBetween(CalendarUtil.parseDefaultDate(bfDataCondition.getBeginTime()), CalendarUtil.parseDefaultDate(bfDataCondition.getEndTime()), pageable);

        long totalElements = orderPage.getTotalElements();
        List<BusinessBigLessonOrder> content = orderPage.getContent();
        if(CollectionUtils.isNotEmpty(content)){
            Set<String> orderNoSet = content.stream().map(businessBigLessonOrder -> businessBigLessonOrder.getOrderNo()).collect(Collectors.toSet());

            //根据订单号查询teacherId的集合
            List<BusinessBigOrderChance> orderChanceList = bigOrderChanceRepository.findAllByOrderNoIn(orderNoSet);
            Map<String, List<BusinessBigOrderChance>> orderNoListMap = orderChanceList.stream().collect(Collectors.groupingBy(o -> o.getOrderNo()));
            Set<Long> teacherIds = orderChanceList.stream().map(businessBigOrderChance -> businessBigOrderChance.getTeacherId()).collect(Collectors.toSet());

            List<BusinessTeacherInfo> teacherInfoList = businessTeacherInfoRepository.findAllByTeacherIdIn(teacherIds);
            Map<Long, List<BusinessTeacherInfo>> teacherInfoMap = teacherInfoList.stream().collect(Collectors.groupingBy(o -> o.getTeacherId()));

            //根据teacherid的集合查询所在组织架构
            List<UserVO> userVOS = miniAdminService.batchFindUserList(teacherIds);
            Map<Long, List<UserVO>> userMap = userVOS.stream().collect(Collectors.groupingBy(o -> o.getId()));

            content.forEach(order -> {
                BfDataVO bfDataVO = new BfDataVO();
                String rowKey = order.getOrderNo() + rowkey_suffix;

                bfDataVO.setCompany_system(company_system);
                bfDataVO.setRowkey(rowKey);

                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                bfDataVO.setData_send_time(dateFormat.format(new Date()));
                bfDataVO.setOrder_number(order.getOrderNo());
                bfDataVO.setPlace_order_time(dateFormat.format(order.getOrderCreateTime()));
                bfDataVO.setPayment_time(dateFormat.format(getPayFinishTime(order)));
                bfDataVO.setFirst_level_project(this.convertSkuName(order.getSkuName()));

                String orderStateStr = order.getOrderStateStr();
                String orderState = order.getOrderState();
                XcxOrderState osEnum = XcxOrderState.getByState(orderState);
                if(osEnum != null){
                    orderStateStr = osEnum.getName();
                }
                bfDataVO.setPayment_status(orderStateStr);

                bfDataVO.setPhone_number(bfEncrypt(decryptField(order.getPhoneNumber())));
                bfDataVO.setGoods_id(order.getLessonId());
                bfDataVO.setGoods_course_name(order.getLessonName());
                bfDataVO.setOrder_turnover(ObjectUtils.toString(order.getPayAmount()));
                bfDataVO.setUsername(order.getUsername());
                bfDataVO.setThird_proj_price(order.getPrice());
                bfDataVO.setLoan_training_amount(order.getPayAmountStage2());

                //根据orderNO找对应teacherId
                List<BusinessBigOrderChance> businessBigOrderChances = orderNoListMap.get(order.getOrderNo());
                if(CollectionUtils.isNotEmpty(businessBigOrderChances)){
                    Long teacherId = businessBigOrderChances.get(0).getTeacherId();

                    //根据teacherId查组织信息
                    List<UserVO> userVOList = userMap.get(teacherId);
                    if(CollectionUtils.isNotEmpty(userVOList)){
                        FullDeptVo fullDept = userVOList.get(0).getFullDept();
                        bfDataVO.setOrg_level_five(fullDept.getOgName());
                        bfDataVO.setOrg_level_four(fullDept.getOdName());
                        bfDataVO.setOrg_level_three(fullDept.getWorkRoomName());
                        bfDataVO.setOrg_level_two(fullDept.getSkuName());
                    }

                    //根据teacherId查信息
                    List<BusinessTeacherInfo> businessTeacherInfos = teacherInfoMap.get(teacherId);
                    bfDataVO.setOrg_level_six(businessTeacherInfos.get(0).getTeacherLoginName());
                }
                bfPackages.add(new BfPackage(rowKey, "event_log.senior_ticket_detail_table", JSONObject.toJSONString(bfDataVO)));
            });
        }

        PageResultVO<BfPackage> bfPackagePageResultVO = new PageResultVO<>();
        bfPackagePageResultVO.setTotal(totalElements);
        bfPackagePageResultVO.setRows(bfPackages);

        return bfPackagePageResultVO;
    }


    private Date getPayFinishTime(BusinessBigLessonOrder order){

        if("15".equals(order.getOrderState()) || "25".equals(order.getOrderState()) || "40".equals(order.getOrderState())){
            if(order.getPayFinishTime() != null){
                return order.getPayFinishTime();
            }else {
                return order.getOrderCreateTime();
            }
        }else {
            return null;
        }

    }
}
